package com.priox.sigar.jsf;


import com.priox.sigar.dto.ReporteContext;
import com.priox.sigar.client.dto.CheckPointDTO;
import com.priox.sigar.client.dto.GrupoEmpresarialDTO;
import com.priox.sigar.domain.model.CheckPoint;
import com.priox.sigar.domain.model.constantes.PathConstant;
import com.priox.sigar.dto.ReporteFlt;
import com.priox.sigar.dto.ReporteValidacionDTO;
import com.priox.sigar.enums.ProcesoEstado;
import com.priox.sigar.enums.TipoCuenta;
import com.priox.sigar.server.infrastructure.persistence.exception.ApplicationException;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.CloseEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;


@ManagedBean
@Scope("session")
@Component
public class ValidarReporteJsfBean extends ReporteCuentaJsfBean {
    private static final Logger LOG = LoggerFactory.getLogger(ValidarReporteJsfBean.class);

    //================================================================================
    // Spring Managed Beans
    //================================================================================

    @Autowired
    protected JobLauncher jobLauncher;

    @Autowired
    @Qualifier("jobResumenExcel")
    private Job jobResumenExcel;

    List<ReporteValidacionDTO> registros = new ArrayList<ReporteValidacionDTO>();
    //================================================================================
    // Form Data
    //================================================================================

    private CheckPointDTO seleccion;

    private ReporteFlt filtro;
    private String numeroDocumento;


    @Override
    protected TipoCuenta getTipoCuenta() {
        return TipoCuenta.CUENTA_X_PAGAR;
    }

    public void procesar(ActionEvent actionEvent) {
        cargarResumen(actionEvent);

    }

    @PostConstruct
    public void init() {
        reporteContext = new ReporteContext();
        nuevoCheckPoint = new CheckPointDTO();
        refreshCheckPoint();
    }

    @Override
    protected List onRegistrosList(String typeReport,ActionEvent actionEvent) {
        return registros;
    }

    @Override
    protected Map onPrintParameter(String typeReport,ActionEvent actionEvent) {
        final String PATH = PathConstant.DIR_JASPER;
        String jasper = PATH + File.separator;
        Map result = new HashMap();
        result.put("fechaGeneracion", new Date());
        result.put("SUBREPORT_DIR", jasper);
        return result;
    }

    public void cargarResumen(ActionEvent actionEvent) {
        nuevoCheckPoint.setCheckPointId(null);
        registros = new ArrayList<ReporteValidacionDTO>();
        if (StringUtils.isBlank(nuevoCheckPoint.getNombreArchivo()) || nuevoCheckPoint.getArchivos().isEmpty()) {
            throw new ApplicationException("El archivo no a sido cargado");
        }
        nuevoCheckPoint.setUsuarioId(getUser().getUsuarioId());
        nuevoCheckPoint.setEstado(ProcesoEstado.BORRADOR);
        nuevoCheckPoint.setTipo(TipoCuenta.CUENTA_RESUMEN);
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        nuevoCheckPoint.setComentario("datos cargados el " + sdf.format(new Date()));
        CheckPoint checkPoint = mapperService.map(nuevoCheckPoint, CheckPoint.class);
        registroCheckPointApp.save(checkPoint, false);
        nuevoCheckPoint.setCheckPointId(checkPoint.getCheckPointId());
        LOG.info("CheckPoint creado <" + nuevoCheckPoint.getCheckPointId() + ">");
        executeJob(nuevoCheckPoint);
        addMessage(successfullyCreatedMsg, FacesMessage.SEVERITY_INFO);
    }

    public Job getJob() {
        return jobResumenExcel;
    }

    public void executeJob(CheckPointDTO checkPointDTO) {
        String archivo = PathConstant.DIR_TMP + File.separator + nuevoCheckPoint.getNombreArchivo();

        JobParametersBuilder jpBuilder = new JobParametersBuilder()
                .addString("input.file.name", archivo)
                .addLong("input.usuarioId", getUser().getUsuarioId())
                .addLong("input.checkPointId", checkPointDTO.getCheckPointId());
        JobExecution execution = null;
        try {
            execution = this.jobLauncher.run(getJob(), jpBuilder.toJobParameters());
            if (ExitStatus.COMPLETED.equals(execution.getExitStatus())) {
                registroCheckPointApp.finalizarResumen(checkPointDTO.getCheckPointId());
                reporteContext.setCheckPointActual(checkPointDTO);
                registros = reporteMapper.findReporteValidacion(reporteContext);
//                registroCheckPointApp.delete(mapperService.map(checkPointDTO, CheckPoint.class));
//                nuevoCheckPoint.setArchivos(new ArrayList<String>());
//                nuevoCheckPoint.setNombreArchivo(null);
//                nuevoCheckPoint.setCheckPointId(null);
                cmbSociedadReporte = checkPointMapper.findSociedades(reporteContext);
                executeModal("wvDiferenciaReporte", true);
            } else {
                throw new ApplicationException("Error al procesar la tarea");
            }
        } catch (ApplicationException e) {
            e.printStackTrace();
            throw e;
        }catch (Exception e) {
            e.printStackTrace();
            throw new ApplicationException("Error al procesar la tarea");
        }

    }

    @Override
    public void setCursorTableNull() {
        seleccion = null;
    }

    @Override
    public void onClean(ActionEvent actionEvent) {

        seleccion = null;
    }

    @Override
    public void onNewRecord(ActionEvent actionEvent) {

    }

    @Override
    public void onFind(ActionEvent actionEvent) {


    }

    public void onSelectFiltro(ActionEvent actionEvent) {
            registros=reporteMapper.findReporteValidacion(reporteContext);
    }


    @Override
    public void onShowEditDialog(ActionEvent actionEvent) {

    }


    @Override
    public void onDelete(ActionEvent actionEvent) {


    }


    public String onDownloadFile(ActionEvent actionEvent) {

        return null;
    }


    @Override
    protected void onDialogClose(CloseEvent event) {

        LOG.debug("Closing CRUD Dialog for Periodo");

    }

    //================================================================================
    // Autocompleters
    //================================================================================


    //================================================================================
    // Accessors
    //================================================================================


    public CheckPointDTO getSeleccion() {
        return seleccion;
    }

    public void setSeleccion(CheckPointDTO seleccion) {
        this.seleccion = seleccion;
    }


    public List<GrupoEmpresarialDTO> getCmbGrupoEmpresarial() {
        return cmbGrupoEmpresarial;
    }

    public void setCmbGrupoEmpresarial(List<GrupoEmpresarialDTO> cmbGrupoEmpresarial) {
        this.cmbGrupoEmpresarial = cmbGrupoEmpresarial;
    }

    public ReporteFlt getFiltro() {
        return filtro;
    }

    public void setFiltro(ReporteFlt filtro) {
        this.filtro = filtro;
    }

    public List<ReporteValidacionDTO> getRegistros() {
        return registros;
    }

    public void setRegistros(List<ReporteValidacionDTO> registros) {
        this.registros = registros;
    }

    public String getNumeroDocumento() {
        return numeroDocumento;
    }

    public void setNumeroDocumento(String numeroDocumento) {
        this.numeroDocumento = numeroDocumento;
    }
}
